package com.example.logaspect.service;

import com.example.logaspect.annotation.LogRecord.LogLevel;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

/**
 * 默认日志记录服务实现
 * @author Senhai Xu
 */
public class DefaultLogRecordServiceImpl implements LogRecordService {

    private static final Logger log = LoggerFactory.getLogger(DefaultLogRecordServiceImpl.class);
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void recordMethodStart(String methodSignature, String description, Object[] args, LogLevel level) {
        String message = String.format("开始执行方法: %s", methodSignature);
        if (StringUtils.hasText(description)) {
            message += String.format(" | 描述: %s", description);
        }

        if (args != null && args.length > 0) {
            try {
                message += String.format(" | 入参: %s", objectMapper.writeValueAsString(args));
            } catch (Exception e) {
                message += String.format(" | 入参: %s (序列化失败)", args);
            }
        }
//debug 不产生输出
        logByLevel(message, level);
    }

    @Override
    public void recordMethodEnd(String methodSignature, String description, Object[] args,
                                Object result, long executionTime, LogLevel level) {
        String message = String.format("方法执行完成: %s | 耗时: %d毫秒", methodSignature, executionTime);
        if (StringUtils.hasText(description)) {
            message += String.format(" | 描述: %s", description);
        }

        if (result != null) {
            try {
                message += String.format(" | 返回值: %s", objectMapper.writeValueAsString(result));
            } catch (Exception e) {
                message += String.format(" | 返回值: %s (序列化失败)", result);
            }
        }

        logByLevel(message, level);
    }

    @Override
    public void recordMethodException(String methodSignature, String description, Object[] args,
                                      Throwable throwable, long executionTime, LogLevel level) {
        String message = String.format("方法执行异常: %s | 耗时: %d毫秒 | 异常: %s",
                methodSignature, executionTime, throwable.getMessage());
        if (StringUtils.hasText(description)) {
            message += String.format(" | 描述: %s", description);
        }

        logByLevel(message, LogLevel.ERROR);
    }

    private void logByLevel(String message, LogLevel level) {

        switch (level) {
            case WARN:
                log.warn(message);
                break;
            case ERROR:
                log.error(message);
                break;
            default:
                log.info(message);
                break;
        }
    }
}